package com.ruoyi.common.enums;

import java.util.function.Function;

import com.ruoyi.common.utils.DesensitizedUtil;

/**
 * 脱敏类型枚举类
 * <p>
 * 定义了常见的数据脱敏类型及其对应的脱敏处理逻辑。每个枚举项都持有一个函数式接口，
 * 用于对原始字符串进行脱敏处理。
 * </p>
 *
 * @author ruoyi
 */
public enum DesensitizedType {
    /**
     * 姓名脱敏：保留姓名的首尾字符，中间字符使用星号(*)替换。
     * 例如："李明" -> "李*"
     */
    USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),

    /**
     * 密码脱敏：将密码全部字符替换为星号(*)。
     * 例如："123456" -> "******"
     */
    PASSWORD(DesensitizedUtil::password),

    /**
     * 身份证号码脱敏：保留前4位和后4位，中间10位替换为星号(*)。
     * 支持18位身份证（含校验位X/x）。
     * 例如："110101199001011234" -> "1101** **** ****1234"
     */
    ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\d{3}[Xx]|\\d{4})", "$1** **** ****$2")),

    /**
     * 手机号码脱敏：保留前3位和后4位，中间4位替换为星号(*)。
     * 例如："13812345678" -> "138****5678"
     */
    PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),

    /**
     * 电子邮箱脱敏：保留第一个字母和@及之后的部分，@之前其余部分替换为星号(*)。
     * 例如："example@domain.com" -> "e****@domain.com"
     */
    EMAIL(s -> s.replaceAll("(^.)[^@]*(@.*$)", "$1****$2")),

    /**
     * 银行卡号脱敏：格式化显示为每四位一组，并隐藏前面的数字，仅保留最后三位数字。
     * 注意：此正则假设卡号长度为18位。
     * 例如："6222001234567890123" -> "**** **** **** **** 0123"
     */
    BANK_CARD(s -> s.replaceAll("\\d{15}(\\d{3})", "**** **** **** **** $1")),

    /**
     * 车牌号码脱敏：调用工具类方法处理普通车辆与新能源车辆的车牌脱敏。
     * 具体实现见 {@link DesensitizedUtil#carLicense(String)}
     */
    CAR_LICENSE(DesensitizedUtil::carLicense);

    /**
     * 存储当前脱敏类型的处理函数
     */
    private final Function<String, String> desensitizer;

    /**
     * 构造函数，初始化脱敏处理函数
     *
     * @param desensitizer 用于执行脱敏操作的函数式接口实现
     */
    DesensitizedType(Function<String, String> desensitizer) {
        this.desensitizer = desensitizer;
    }

    /**
     * 获取当前脱敏类型的处理函数
     *
     * @return 返回一个 Function<String, String> 类型的脱敏处理函数
     */
    public Function<String, String> desensitizer() {
        return desensitizer;
    }
}
